#include "widget_funcd_weather.h"
#include "ui_widget_funcd_weather.h"
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QMessageBox>
#include <QDateTime>
#include <QRegularExpression>
#include <QGraphicsSimpleTextItem>

Widget_funcD_Weather::Widget_funcD_Weather(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget_funcD_Weather)
    , networkManager(new QNetworkAccessManager(this))
{
    ui->setupUi(this);
    setWindowTitle("天气预报系统");

    // 主窗口美化
    this->setStyleSheet(
        "WeatherWidget {"
        "   background: qlineargradient(x1:0, y1:0, x2:1, y2:1,"
        "               stop:0 #ECEFF1, stop:1 #CFD8DC);"
        "   font-family: 'Microsoft YaHei';"
        "}"
    );
    
    // 状态标签样式
    ui->statusLabel->setStyleSheet(
        "QLabel {"
        "   background-color: #F0FFF0;"  //浅绿
        "   color: black;"
        "   padding: 6px;"
        "   border-radius: 4px;"
        "}"
    );

    // 图表视图样式
    ui->chartView->setStyleSheet(
        "QGraphicsView {"
        "   border: 1px solid #B0BEC5;"
        "   border-radius: 8px;"
        "   background: white;"
        "}"
    );
    //搜索框样式
    ui->cityEdit->setStyleSheet(R"(
        QLineEdit {
            border: 2px solid #87CEFA;
            border-radius: 8px;
            padding: 8px 12px;
            font-size: 14px;
            background-color: #FFFFFF;
        }
        QLineEdit:focus {
            border-color: #5CACEE;
            box-shadow: 0 0 5px rgba(42, 125, 225, 0.5);
        }
    )");
    //无边框窗口
    //setWindowFlags(Qt::FramelessWindowHint);
    
    // 加载城市代码
    loadCityCodes();

    // 连接信号槽
    connect(ui->searchButton, &QPushButton::clicked, this, &Widget_funcD_Weather::on_searchButton_clicked);
    // 输入框回车键事件连接
    connect(ui->cityEdit, &QLineEdit::returnPressed, this, &Widget_funcD_Weather::on_searchButton_clicked);
    
    connect(networkManager, &QNetworkAccessManager::finished, this, &Widget_funcD_Weather::onWeatherDataReady);
}

Widget_funcD_Weather::~Widget_funcD_Weather()
{   
    delete ui;
    delete networkManager;
}

/**
 * @brief 加载城市代码映射表
 * 
 * 从资源文件中读取城市名称与城市代码的对应关系，
 * 并存储到cityCodeMap中供查询使用
 */
void Widget_funcD_Weather::loadCityCodes()
{
    // 打开城市代码文件（资源文件）
    QFile file(":/img/city.txt");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        QMessageBox::warning(this, "警告", "无法加载城市代码文件！");
        return;
    }
    
    // 清空原有数据
    cityCodeMap.clear();
    cityNameList.clear();  // 新增：存储城市名称列表

    // 逐行读取文件内容
    while (!file.atEnd()) {
        // 按空白字符分割每行内容
        QStringList parts = QString(file.readLine()).split(QRegExp("\\s+"), Qt::SkipEmptyParts);
        
        // 确保每行至少包含城市代码和城市名称两部分
        if (parts.size() >= 2) {
            // 将城市名称作为key，城市代码作为value存入map
            cityCodeMap.insert(parts[1], parts[0]);
            cityNameList.append(parts[1]);          // 新增：存储城市名称 
        }
    }
    file.close();  // 关闭文件
    // 初始化 QCompleter（新增）
    initCompleter();
}

/**
 * @brief 根据城市名称获取城市代码
 * @param cityName 城市名称
 * @return 对应的城市代码，如果找不到则返回空字符串
 */
QString Widget_funcD_Weather::getCityCode(const QString &cityName)
{
    // 从map中查找城市代码，找不到则返回空字符串
    return cityCodeMap.value(cityName, "");
}

/**
 * @brief 搜索按钮点击事件处理函数
 * 
 * 根据用户输入的城市名称查询天气信息
 */
void Widget_funcD_Weather::on_searchButton_clicked()
{
    // 获取并处理用户输入的城市名称
    QString cityName = ui->cityEdit->text().trimmed();
    if (cityName.isEmpty()) {
        QMessageBox::warning(this, "警告", "请输入城市名称！");
        return;
    }

    // 查询城市代码
    QString cityCode = getCityCode(cityName);
    if (cityCode.isEmpty()) {
        QMessageBox::warning(this, "警告", "未找到该城市的代码！");
        return;
    }

    // 构造天气API请求URL
    QUrl url(QString("http://t.weather.itboy.net/api/weather/city/%1").arg(cityCode));
    
    // 发送网络请求
    networkManager->get(QNetworkRequest(url));
    
    // 更新UI状态
    ui->statusLabel->setText("正在查询天气数据...");
}
void Widget_funcD_Weather::onWeatherDataReady(QNetworkReply *reply)
{
    if (reply->error() != QNetworkReply::NoError) {
        ui->statusLabel->setText("查询失败: " + reply->errorString());
        reply->deleteLater();
        return;
    }

    parseWeatherData(reply->readAll());
    reply->deleteLater();
}

void Widget_funcD_Weather::parseWeatherData(const QByteArray &data)
{
    QJsonDocument doc = QJsonDocument::fromJson(data);
    if (doc.isNull() || !doc.isObject()) {
        ui->statusLabel->setText("解析天气数据失败！");
        return;
    }

    QJsonObject rootObj = doc.object();
    if (rootObj.value("status").toInt() != 200) {
        ui->statusLabel->setText("API返回错误: " + rootObj.value("message").toString());
        return;
    }
    // 从JSON根对象中获取"data"字段并转换为QJsonObject
    // 这里rootObj是解析后的天气API返回的JSON对象
    QJsonObject dataObj = rootObj.value("data").toObject();
    QJsonArray forecastArray = dataObj.value("forecast").toArray();

    // 清空现有数据
    ui->weatherTable->setRowCount(0);
    ui->weatherTable->setRowCount(forecastArray.size());

    // 准备图表数据
    QtCharts::QLineSeries *highTempSeries = new QtCharts::QLineSeries();
    QtCharts::QLineSeries *lowTempSeries = new QtCharts::QLineSeries();
    highTempSeries->setName("最高气温");
    lowTempSeries->setName("最低气温");

    QStringList dates;
    double minTemp = std::numeric_limits<double>::max();
    double maxTemp = std::numeric_limits<double>::min();
// 遍历预报数据数组
    for (int i = 0; i < forecastArray.size(); ++i) {
        // 获取单日预报对象
        QJsonObject dayObj = forecastArray[i].toObject();
        // 解析具体字段（根据天气API的实际返回结构）
        QString originalYmd = dayObj.value("ymd").toString();  //年月日
        QString originalDate = dayObj.value("date").toString(); //日期
        QString type = dayObj.value("type").toString();
        QString highTemp = dayObj.value("high").toString();
        QString lowTemp = dayObj.value("low").toString();
        QString fx = dayObj.value("fx").toString();
        QString fl = dayObj.value("fl").toString();
        QString notice = dayObj.value("notice").toString();
        
        // 解析并重新格式化日期
           QString formattedDate;
           // 假设原始格式是 "yyyy-MM-dd"
           QDate date = QDate::fromString(originalYmd, "yyyy-MM-dd");  // 假设原始格式是 "yyyy-MM-dd"
           if (date.isValid()) {
               formattedDate = date.toString("yyyy年MM月dd日");  // 转换为 "2023年05月15日"
           } else {
               // 如果解析失败，尝试其他格式或保留原样
               qWarning() << "无法解析日期格式:" << originalYmd;
               formattedDate = originalYmd;  //  fallback，直接显示原始数据
           }
        // 改进的温度字符串处理
        auto extractTemperature = [](const QString &tempStr) -> double {
            // 示例格式处理："高温 28℃" 或 "28℃" 或 "28"
            QRegularExpression re("(-?\\d+)"); // 匹配数字（包括负数）
            QRegularExpressionMatch match = re.match(tempStr);
            if (match.hasMatch()) {
                bool ok;
                double temp = match.captured(1).toDouble(&ok);
                if (ok) return temp;
            }
            qWarning() << "无法解析温度字符串:" << tempStr;
            return 0.0; // 返回默认值或抛出异常
        };

        double highTempValue = extractTemperature(highTemp);
        double lowTempValue = extractTemperature(lowTemp);

        // 更新最小最大值
        if (highTempValue > maxTemp) maxTemp = highTempValue;
        if (lowTempValue < minTemp) minTemp = lowTempValue;

        // 添加到表格
        int row = ui->weatherTable->rowCount() - forecastArray.size() + i;
        ui->weatherTable->setItem(row, 0, new QTableWidgetItem(formattedDate));
        //ui->weatherTable->setItem(row, 1, new QTableWidgetItem(type));
        ui->weatherTable->setItem(row, 2, new QTableWidgetItem(QString::number(highTempValue) + "℃"));
        ui->weatherTable->setItem(row, 3, new QTableWidgetItem(QString::number(lowTempValue) + "℃"));
        ui->weatherTable->setItem(row, 4, new QTableWidgetItem(fx));
        ui->weatherTable->setItem(row, 5, new QTableWidgetItem(fl));
        ui->weatherTable->setItem(row, 6, new QTableWidgetItem(notice));
        
        // 在表格数据填充部分添加天气图标
        auto getWeatherIcon = [](const QString &weatherType) -> QIcon {
            if (weatherType.contains("晴")) return QIcon(":/晴");
            if (weatherType.contains("云")) return QIcon(":/多云");
            if (weatherType.contains("雨")) return QIcon(":/雨");
            if (weatherType.contains("雪")) return QIcon(":/雪");
            return QIcon(":/阴");
        };
        
        // 在表格填充循环中添加
        QTableWidgetItem *weatherItem = new QTableWidgetItem(getWeatherIcon(type), type);
        ui->weatherTable->setItem(row, 1, weatherItem);
        // 添加到图表数据
        dates << originalDate;
        highTempSeries->append(i, highTempValue);
        lowTempSeries->append(i, lowTempValue);

        qDebug() << "日期:" << date 
                 << "高温:" << highTempValue 
                 << "低温:" << lowTempValue;
    }

    // 设置图表
    QtCharts::QChart *chart = new QtCharts::QChart();
    chart->addSeries(highTempSeries);
    chart->addSeries(lowTempSeries);
    chart->setTitle("一周气温变化");
    chart->setAnimationOptions(QtCharts::QChart::SeriesAnimations);
    
    // X轴（日期）
    QtCharts::QBarCategoryAxis *axisX = new QtCharts::QBarCategoryAxis();
    axisX->append(dates);
    chart->addAxis(axisX, Qt::AlignBottom);
    highTempSeries->attachAxis(axisX);
    lowTempSeries->attachAxis(axisX);

    // Y轴（温度）
    QtCharts::QValueAxis *axisY = new QtCharts::QValueAxis();
    axisY->setTitleText("温度(℃)");
    axisY->setVisible(false); //隐藏y轴
    
    // 在设置图表的部分添加以下美化代码
    
    // 设置高温曲线样式
    highTempSeries->setPen(QPen(QColor("#FF5722"), 2)); // 橙色，线宽2
    highTempSeries->setPointsVisible(true); // 显示数据点
    highTempSeries->setPointLabelsVisible(true); // 显示数值标签
    highTempSeries->setPointLabelsFormat("@yPoint℃"); // 标签格式
    highTempSeries->setPointLabelsColor(QColor("#FF5722")); // 标签颜色
    highTempSeries->setPointLabelsFont(QFont("华文仿宋", 8, QFont::Bold)); // 标签字体
    highTempSeries->setPointLabelsClipping(false); // 防止标签被裁剪
    
    // 设置低温曲线样式
    lowTempSeries->setPen(QPen(QColor("#2196F3"), 2)); // 蓝色，线宽2
    lowTempSeries->setPointsVisible(true);
    lowTempSeries->setPointLabelsVisible(true);
    lowTempSeries->setPointLabelsFormat("@yPoint℃");
    lowTempSeries->setPointLabelsColor(QColor("#2196F3"));
    lowTempSeries->setPointLabelsFont(QFont("华文仿宋", 8, QFont::Bold));
    lowTempSeries->setPointLabelsClipping(false);
    
    // 设置图表背景和主题
    //chart->setTheme(QtCharts::QChart::ChartThemeLight); // 使用浅色主题
    chart->setBackgroundBrush(QBrush(QColor("#AFEEEE"))); // 蓝绿色背景，使用画刷
    chart->setBackgroundRoundness(10); // 圆角背景
    
    // 设置坐标轴样式
    axisX->setLabelsFont(QFont("Arial", 9));
//    axisY->setLabelsFont(QFont("Arial", 9));
//    axisY->setGridLineColor(QColor("#E0E0E0"));
    
    // 动态设置Y轴范围（至少显示10度范围）
    double rangeMin = qMin(minTemp - 5, 0.0); // 向下多留5度空间
    double rangeMax = qMax(maxTemp + 15, 15.0); // 向上多留15度空间
    if (rangeMax - rangeMin < 10) {
        double mid = (rangeMin + rangeMax) / 2;
        rangeMin = mid - 5;
        rangeMax = mid + 10;
    }
    axisY->setRange(rangeMin, rangeMax);
    
    chart->addAxis(axisY, Qt::AlignLeft);
    highTempSeries->attachAxis(axisY);
    lowTempSeries->attachAxis(axisY);
   
    // 设置表头
    QStringList headers = {"日期", "天气", "最高温", "最低温", "风向", "风力", "提示"};
    ui->weatherTable->setHorizontalHeaderLabels(headers);
    ui->weatherTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); // 自动调整列宽
    
    // 设置交替行颜色
    ui->weatherTable->setAlternatingRowColors(true);
    
    // 设置温度列的特殊颜色
    for (int row = 0; row < ui->weatherTable->rowCount(); ++row) {
        ui->weatherTable->item(row, 2)->setForeground(QColor("#FF5722")); // 高温橙色
        ui->weatherTable->item(row, 3)->setForeground(QColor("#2196F3")); // 低温蓝色
    }
    // 美化图表
    chart->setBackgroundBrush(QBrush(Qt::white));
    
    // 显示图表
    chart->legend()->setVisible(true);
    chart->legend()->setAlignment(Qt::AlignBottom);

    // 清除旧图表
    if (ui->chartView->chart()) {
        delete ui->chartView->chart();
    }
    ui->chartView->setChart(chart);
    ui->chartView->setRenderHint(QPainter::Antialiasing);

    ui->statusLabel->setText("天气数据更新成功！");    
    // 在设置表格数据后添加以下美化代码
    // 设置表格整体样式
    ui->weatherTable->setAlternatingRowColors(true);
    ui->weatherTable->setStyleSheet(
        "QTableWidget {"
        "   background-color: #F5F5DC;"
        "   alternate-background-color: #E6E6FA;" //表格背景色
        "   gridline-color: #E0E0E0;"
        "   font-family: Arial;"
        "}"
        "QHeaderView::section {"
        "   background-color: #FFF0F5 !important;" //淡粉色背景
        "   color: black;"           //字体颜色
        "   padding: 4px;"
        "   border: none;"      //无边框
        "   font-weight: bold;" //文字加粗
        "}"
        "QTableWidget::item {"
        "   padding: 4px;"
        "}"
    );
    
    qDebug() << ui->weatherTable->styleSheet();
}

//模糊搜索功能实现
void Widget_funcD_Weather::initCompleter()
{
    // 创建 QCompleter 并设置数据源
    QCompleter *completer = new QCompleter(cityNameList, this);
    completer->setFilterMode(Qt::MatchStartsWith);  // 前缀匹配
    completer->setCaseSensitivity(Qt::CaseInsensitive);  // 大小写不敏感
    completer->setWrapAround(false);  // 不循环选择

    // 设置到搜索框
    ui->cityEdit->setCompleter(completer);
    
    //下拉状态栏样式
    completer->popup()->setStyleSheet(
        "QListView { background: white; color: black; }"
        "QListView::item:hover { background: lightblue; }"
        "QListView::item:selected { background: blue; color: white; }"
    );
}
